<template>
  <div class="stats-row">
    <el-card class="stat-card">
      <div class="stat-title">文案总数</div>
      <div class="stat-value">{{ totalCount }}</div>
    </el-card>
    <el-card class="stat-card">
      <div class="stat-title">分类数</div>
      <div class="stat-value">{{ categoryCount }}</div>
    </el-card>
    <el-card class="stat-card">
      <div class="stat-title">今日新增</div>
      <div class="stat-value">{{ todayCount }}</div>
    </el-card>
  </div>
  <el-card>
    <div class="toolbar">
      <el-input v-model="search" placeholder="搜索文案内容/标题" style="width: 260px; margin-right: 16px;" clearable />
      <el-tree-select
        v-model="category"
        :data="categoriesTree"
        :props="{ label: 'name', value: 'id', children: 'children' }"
        placeholder="全部分类"
        check-strictly
        style="width: 160px; margin-right: 16px;"
      />
      <el-button type="primary" @click="openForm()">新增文案</el-button>
      <el-button @click="showCategoryDialog = true">分类管理</el-button>
    </div>
    <el-table :data="filteredList" border stripe style="margin-top: 18px;">
      <el-table-column prop="icon" label="图标" width="80">
        <template #default="scope">
          <img v-if="scope.row.icon" :src="scope.row.icon" style="width:32px;height:32px;object-fit:contain;" />
        </template>
      </el-table-column>
      <el-table-column prop="title" label="标题" width="200" />
      <el-table-column prop="content" label="内容">
        <template #default="scope">
          <div class="table-content-ellipsis">{{ stripHtml(scope.row.content) }}</div>
        </template>
      </el-table-column>
      <el-table-column prop="category" label="分类" width="120">
        <template #default="scope">
          {{ getCategoryNameById(scope.row.category, categoriesTree) }}
        </template>
      </el-table-column>
      <el-table-column prop="weight" label="权重" width="80" />
      <el-table-column prop="updatedAt" label="更新时间" width="160" />
      <el-table-column prop="readCount" label="阅读量" width="90" />
      <el-table-column prop="status" label="状态" width="80">
        <template #default="scope">
          <el-tag v-if="scope.row.status === 'published'" type="success">发布</el-tag>
          <el-tag v-else type="info">草稿</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="260">
        <template #default="scope">
          <div style="display: flex; gap: 8px;">
            <el-button size="small" @click="openForm(scope.row)">编辑</el-button>
            <el-button size="small" type="danger" @click="onDelete(scope.row)">删除</el-button>
            <el-button size="small" @click="onPreview(scope.row)">预览</el-button>
            <el-button size="small" @click="onShare(scope.row)">分享</el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog v-model="showForm" :title="form.id ? '编辑文案' : '新增文案'" width="700px">
      <el-form :model="form" label-width="80px">
        <el-form-item label="图标">
          <el-upload
            class="icon-uploader"
            :show-file-list="false"
            :before-upload="beforeIconUpload"
            :on-change="handleIconChange"
            :on-remove="handleIconRemove"
            :file-list="iconFileList"
            accept="image/*"
            list-type="picture-card"
            :auto-upload="false"
          >
            <img v-if="form.icon" :src="form.icon" class="icon-preview" />
            <i v-else class="el-icon-plus"></i>
          </el-upload>
        </el-form-item>
        <el-form-item label="主图">
          <el-upload
            class="main-image-uploader"
            :show-file-list="false"
            :before-upload="beforeMainImageUpload"
            :on-change="handleMainImageChange"
            :on-remove="handleMainImageRemove"
            accept="image/*"
            list-type="picture-card"
            :auto-upload="false"
          >
            <img v-if="form.mainImage" :src="form.mainImage" class="main-image-preview" />
            <i v-else class="el-icon-plus"></i>
          </el-upload>
        </el-form-item>
        <el-form-item label="缩略图">
          <el-upload
            class="thumb-image-uploader"
            :show-file-list="false"
            :before-upload="beforeThumbImageUpload"
            :on-change="handleThumbImageChange"
            :on-remove="handleThumbImageRemove"
            accept="image/*"
            list-type="picture-card"
            :auto-upload="false"
          >
            <img v-if="form.thumbImage" :src="form.thumbImage" class="thumb-image-preview" />
            <i v-else class="el-icon-plus"></i>
          </el-upload>
        </el-form-item>
        <el-form-item label="权重">
          <el-input-number v-model="form.weight" :min="1" :max="9999" />
        </el-form-item>
        <el-form-item label="标题">
          <el-input v-model="form.title" style="width: 100%;" />
        </el-form-item>
        <el-form-item label="分类">
          <el-tree-select
            v-model="form.category"
            :data="categoriesTree"
            :props="{ label: 'name', value: 'id', children: 'children' }"
            placeholder="请选择分类"
            check-strictly
            style="width: 100%;"
          />
        </el-form-item>
        <el-form-item label="内容">
          <div style="width: 100%;">
            <QuillEditor
              v-model:content="form.content"
              contentType="html"
              style="min-height:320px; width:100%; background:#fff; border-radius:4px;"
              toolbar="full"
            />
          </div>
        </el-form-item>
        <el-form-item label="状态">
          <el-radio-group v-model="form.status">
            <el-radio label="published">发布</el-radio>
            <el-radio label="draft">草稿</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showForm = false">取消</el-button>
        <el-button type="primary" @click="onSave">保存</el-button>
      </template>
    </el-dialog>
    <el-dialog v-model="showPreview" title="文案预览" width="700px">
      <el-tabs v-model="previewMode" style="margin-bottom: 12px;">
        <el-tab-pane label="PC端预览" name="pc" />
        <el-tab-pane label="H5预览" name="h5" />
      </el-tabs>
      <div v-if="previewMode === 'pc'">
        <div v-html="previewContent" style="min-height:120px; background:#fff; padding:24px; border-radius:8px;" />
      </div>
      <div v-else class="h5-preview-wrap">
        <div class="h5-preview-phone">
          <div v-html="previewContent" class="h5-preview-content" />
        </div>
      </div>
      <template #footer>
        <el-button @click="showPreview = false">关闭</el-button>
      </template>
    </el-dialog>
  </el-card>
  <el-dialog v-model="showCategoryDialog" title="分类管理" width="400px">
    <el-tree
      ref="categoryTreeRef"
      :data="categoriesTree"
      node-key="id"
      :props="{ label: 'name', children: 'children' }"
      default-expand-all
      highlight-current
      style="margin-bottom: 12px;"
    >
      <template #default="{ node, data }">
        <div class="category-node-row">
          <el-upload
            :show-file-list="false"
            :before-upload="beforeCategoryIconUpload"
            :on-change="(file: any) => handleCategoryIconChange(file, data)"
            accept="image/*"
            list-type="picture-card"
            :auto-upload="false"
            class="category-icon-upload"
          >
            <img v-if="data.icon" :src="data.icon" class="category-icon-img" />
            <i v-else class="el-icon-plus category-icon-plus"></i>
          </el-upload>
          <span>{{ data.name }}</span>
          <el-button size="small" type="text" @click.stop="removeCategory(data, node.parent.data)">删除</el-button>
          <el-button size="small" type="text" @click.stop="showAddChildInput(data)">+</el-button>
        </div>
        <div v-if="addingNodeId === data.id" style="margin-top:6px;display:flex;gap:4px;">
          <el-input v-model="newChildName" size="small" placeholder="子分类名称" style="width:110px;" @keyup.enter="confirmAddChild(data)" />
          <el-button size="small" type="primary" @click="confirmAddChild(data)">确定</el-button>
          <el-button size="small" @click="cancelAddChild">取消</el-button>
        </div>
      </template>
    </el-tree>
    <div style="display:flex;gap:8px;">
      <el-input v-model="newCategoryName" placeholder="新根分类名称" size="small" style="flex:1;" />
      <el-button size="small" type="primary" @click="addCategory()">添加到根</el-button>
    </div>
    <template #footer>
      <el-button @click="showCategoryDialog = false">关闭</el-button>
    </template>
  </el-dialog>
  <el-dialog v-model="showShareDialog" title="分享文案" width="400px">
    <div style="display: flex; flex-direction: column; align-items: center; gap: 18px;">
      <QrcodeVue :value="shareUrl" :size="160" />
      <el-input v-model="shareUrl" readonly style="width: 100%;" />
      <el-button type="primary" @click="copyShareUrl" style="width: 100%;">复制链接</el-button>
      <div style="color: #888; font-size: 13px;">可扫码或复制链接访问独立文章页面</div>
    </div>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css'
import { ref as vueRef } from 'vue'
import { nextTick } from 'vue'
import { onBeforeUnmount } from 'vue'
import type { IDomEditor } from '@wangeditor/editor'
// 引入二维码组件
import QrcodeVue from 'qrcode.vue'
import { list, categoriesTree, getCategoryNameById, getNextCategoryId } from './copywriting-data'

// 分类树结构
// 删除本地 const categoriesTree = ...、let categoryIdSeed = ...、const list = ...、export function getCategoryNameById ... 的定义，只保留 import { list, categoriesTree, getCategoryNameById } from './copywriting-data'
const search = ref('')
const category = ref<number | ''>('')
const showForm = ref(false)
const form = reactive<{ id: number, title: string, content: string, category: number, icon: string, weight: number, mainImage: string, thumbImage: string, readCount: number, status: string }>({ id: 0, title: '', content: '', category: 0, icon: '', weight: 1, mainImage: '', thumbImage: '', readCount: 0, status: 'draft' })
const filteredList = computed(() => {
  return list.value.filter(item => {
    const matchSearch = !search.value || item.title.includes(search.value) || item.content.includes(search.value)
    const matchCat = !category.value || item.category === category.value
    return matchSearch && matchCat
  })
})
function openForm(row?: any) {
  if (row) Object.assign(form, row)
  else Object.assign(form, { id: 0, title: '', content: '', category: 0, icon: '', weight: 1, mainImage: '', thumbImage: '', readCount: 0, status: 'draft' })
  showForm.value = true
}
function stripHtml(html: string) {
  return html.replace(/<[^>]+>/g, '').replace(/&nbsp;/g, ' ')
}
function isQuillContentEmpty(html: string) {
  if (!html) return true
  const div = document.createElement('div')
  div.innerHTML = html
  const text = div.innerText.replace(/\u200B/g, '').trim()
  return !text
}
function onSave() {
  console.log('form.content:', form.content)
  console.log('isQuillContentEmpty:', isQuillContentEmpty(form.content))
  if (!form.title) return ElMessage.warning('请填写标题')
  if (!form.category) return ElMessage.warning('请选择分类')
  if (isQuillContentEmpty(form.content)) return ElMessage.warning('请填写内容')
  if (!form.weight) return ElMessage.warning('请填写权重')
  // 权重校验：同分类下不能重复
  const conflict = list.value.some(item => item.category === form.category && item.weight === form.weight && item.id !== form.id)
  if (conflict) return ElMessage.error('同一分类下权重值不能重复')
  if (form.id && form.id !== 0) {
    const idx = list.value.findIndex(i => i.id === form.id)
    if (idx > -1) list.value[idx] = { ...form, updatedAt: new Date().toLocaleString() }
    ElMessage.success('编辑成功')
  } else {
    const newId = Date.now()
    list.value.unshift({ ...form, id: newId, updatedAt: new Date().toLocaleString() })
    ElMessage.success('新增成功')
  }
  showForm.value = false
}
function onDelete(row: any) {
  list.value = list.value.filter(i => i.id !== row.id)
  ElMessage.success('删除成功')
}

const totalCount = computed(() => list.value.length)
const categoryCount = computed(() => {
  const set = new Set(list.value.map(i => i.category))
  return set.size
})
const todayCount = computed(() => {
  const today = new Date().toLocaleDateString()
  return list.value.filter(i => {
    const date = new Date(i.updatedAt).toLocaleDateString()
    return date === today
  }).length
})

const showPreview = ref(false)
const previewContent = ref('')
const previewMode = ref<'pc' | 'h5'>('pc')
function onPreview(row: any) {
  previewContent.value = row.content
  showPreview.value = true
}
const showShareDialog = ref(false)
const shareUrl = ref('')
function onShare(row: any) {
  shareUrl.value = `${window.location.origin}/copywriting/${row.id}`
  showShareDialog.value = true
}
function copyShareUrl() {
  if (navigator.clipboard) {
    navigator.clipboard.writeText(shareUrl.value)
      .then(() => ElMessage.success('分享链接已复制到剪贴板'))
      .catch(() => ElMessage.error('复制失败'))
  } else {
    const textarea = document.createElement('textarea')
    textarea.value = shareUrl.value
    document.body.appendChild(textarea)
    textarea.select()
    try {
      document.execCommand('copy')
      ElMessage.success('分享链接已复制到剪贴板')
    } catch {
      ElMessage.error('复制失败')
    }
    document.body.removeChild(textarea)
  }
}

// 分类管理弹窗
const showCategoryDialog = ref(false)
const categoryTreeRef = ref()
const currentCategoryNode = ref<any>(null)
const currentCategoryNodeIns = ref<any>(null)
const newCategoryName = ref('')
// 控制哪个节点处于添加子分类状态
const addingNodeId = ref<number | null>(null)
const newChildName = ref('')
function handleNodeClick(data: any, node: any) {
  currentCategoryNode.value = data
}
function addCategory(parent?: any) {
  const name = newCategoryName.value.trim()
  if (!name) return ElMessage.warning('请输入分类名称')
  const newNode = { id: getNextCategoryId(), name, icon: '', children: [] }
  if (parent && parent.id) {
    // 递归查找并插入
    function insertToTree(tree: any[]) {
      for (const node of tree) {
        if (node.id === parent.id) {
          node.children.push(newNode)
          return true
        }
        if (node.children && node.children.length) {
          if (insertToTree(node.children)) return true
        }
      }
      return false
    }
    insertToTree(categoriesTree.value)
  } else {
    categoriesTree.value.push(newNode)
  }
  newCategoryName.value = ''
}
function removeCategory(node: any, parent: any) {
  if (parent) {
    parent.children = parent.children.filter((c: any) => c.id !== node.id)
  } else {
    categoriesTree.value = categoriesTree.value.filter((c: any) => c.id !== node.id)
  }
}
function showAddChildInput(node: any) {
  addingNodeId.value = node.id
  newChildName.value = ''
}
function confirmAddChild(node: any) {
  const name = newChildName.value.trim()
  if (!name) return ElMessage.warning('请输入子分类名称')
  const newNode = { id: getNextCategoryId(), name, icon: '', children: [] }
  node.children.push(newNode)
  addingNodeId.value = null
  newChildName.value = ''
}
function cancelAddChild() {
  addingNodeId.value = null
  newChildName.value = ''
}

function beforeIconUpload(file: File) {
  const isImg = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isImg) ElMessage.error('只能上传图片文件')
  if (!isLt2M) ElMessage.error('图片大小不能超过2MB')
  return isImg && isLt2M
}
const iconFileList = ref([])
function handleIconChange(file: any) {
  const reader = new FileReader()
  reader.onload = e => {
    form.icon = e.target?.result as string
  }
  reader.readAsDataURL(file.raw)
}
function handleIconRemove() {
  form.icon = ''
}

function beforeMainImageUpload(file: File) {
  const isImg = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isImg) ElMessage.error('只能上传图片文件')
  if (!isLt2M) ElMessage.error('图片大小不能超过2MB')
  return isImg && isLt2M
}
function handleMainImageChange(file: any) {
  const reader = new FileReader()
  reader.onload = e => {
    form.mainImage = e.target?.result as string
  }
  reader.readAsDataURL(file.raw)
}
function handleMainImageRemove() {
  form.mainImage = ''
}
function beforeThumbImageUpload(file: File) {
  const isImg = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isImg) ElMessage.error('只能上传图片文件')
  if (!isLt2M) ElMessage.error('图片大小不能超过2MB')
  return isImg && isLt2M
}
function handleThumbImageChange(file: any) {
  const reader = new FileReader()
  reader.onload = e => {
    form.thumbImage = e.target?.result as string
  }
  reader.readAsDataURL(file.raw)
}
function handleThumbImageRemove() {
  form.thumbImage = ''
}

function beforeCategoryIconUpload(file: File) {
  const isImg = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 2
  if (!isImg) ElMessage.error('只能上传图片文件')
  if (!isLt2M) ElMessage.error('图片大小不能超过2MB')
  return isImg && isLt2M
}
function handleCategoryIconChange(file: { raw: File }, data: any) {
  const reader = new FileReader()
  reader.onload = e => {
    data.icon = e.target?.result as string
  }
  reader.readAsDataURL(file.raw)
}
</script>

<style scoped>
.toolbar {
  margin-bottom: 16px;
  display: flex;
  gap: 12px;
}
.stats-row {
  display: flex;
  gap: 18px;
  margin-bottom: 18px;
}
.stat-card {
  flex: 1;
  text-align: center;
  padding: 12px 0;
}
.stat-title {
  color: #888;
  font-size: 14px;
  margin-bottom: 6px;
}
.stat-value {
  font-size: 24px;
  font-weight: bold;
  color: #409eff;
}
.icon-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 60px;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.icon-preview {
  width: 60px;
  height: 60px;
  object-fit: contain;
  border-radius: 6px;
}
.h5-preview-wrap {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 400px;
}
.h5-preview-phone {
  width: 375px;
  height: 667px;
  background: #f5f5f5;
  border: 1px solid #ccc;
  border-radius: 32px;
  box-shadow: 0 4px 24px rgba(0,0,0,0.08);
  overflow: auto;
  padding: 24px 12px;
  position: relative;
  margin: 0 auto;
}
.h5-preview-content {
  width: 100%;
  min-height: 100px;
  word-break: break-all;
  font-size: 16px;
  color: #222;
}
.main-image-uploader .el-upload, .thumb-image-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.main-image-preview, .thumb-image-preview {
  width: 80px;
  height: 80px;
  object-fit: contain;
  border-radius: 6px;
}
.table-content-ellipsis {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-all;
  white-space: normal;
  min-height: 24px;
  max-height: 40px;
  font-size: 14px;
  line-height: 1.4;
}
.category-node-row {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 32px;
  min-height: 32px;
  line-height: 32px;
}
.category-node-row .el-button--text {
  padding: 0 2px !important;
  font-size: 13px !important;
  height: 20px !important;
  line-height: 20px !important;
  min-height: 20px !important;
  margin: 0 !important;
}
.category-icon-upload {
  width: 24px !important;
  height: 24px !important;
  min-width: 24px !important;
  min-height: 24px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  margin-right: 2px !important;
  padding: 0 !important;
}
.category-icon-img {
  width: 24px !important;
  height: 24px !important;
  object-fit: contain !important;
  border-radius: 3px !important;
  display: block !important;
  background: #f5f5f5;
  box-sizing: border-box;
}
.category-icon-plus {
  font-size: 18px !important;
  color: #bbb !important;
  display: block !important;
  line-height: 24px !important;
}
.category-node-row span {
  font-size: 15px;
  font-weight: 500;
  vertical-align: middle;
}
/* 强制 el-tree 节点高度与内容一致 */
:deep(.el-tree-node__content) {
  height: 32px !important;
  min-height: 32px !important;
  line-height: 32px !important;
  padding: 0 4px !important;
}
/* 缩进线高度同步 */
:deep(.el-tree-node__expand-icon),
:deep(.el-tree-node__indent),
:deep(.el-tree-node__content > .el-tree-node__expand-icon) {
  height: 32px !important;
  line-height: 32px !important;
  min-height: 32px !important;
  display: flex;
  align-items: center;
}
/* 缩进线本身（虚线）高度同步 */
:deep(.el-tree-node__indent) {
  height: 32px !important;
  min-height: 32px !important;
  display: flex;
  align-items: center;
}
/* 强制上传框为24x24，内部所有元素都不能撑开 */
.category-icon-upload,
:deep(.category-icon-upload.el-upload),
:deep(.category-icon-upload.el-upload--picture-card),
:deep(.category-icon-upload .el-upload),
:deep(.category-icon-upload .el-upload--picture-card),
:deep(.category-icon-upload .el-upload-dragger),
:deep(.category-icon-upload .el-upload-list) {
  width: 24px !important;
  height: 24px !important;
  min-width: 24px !important;
  min-height: 24px !important;
  max-width: 24px !important;
  max-height: 24px !important;
  box-sizing: border-box !important;
  padding: 0 !important;
  margin: 0 !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  overflow: hidden !important;
}
</style> 